#!  /usr/bin/env pytreon
#ecoding=utf
from queue import Queue,Empty,Full
from threading import Lock
from selenium import webdriver
from selenium.webdriver.common.desired_capabilities import DesiredCapabilities
from requests import Session
from selenium.webdriver import PhantomJS,Chrome
from user_agent import generate_user_agent
from ..setting import *


class SafeObjectPool():
    queue = Queue()
    locker = Lock()
    tomJsDriver=r'driver\phantomjs.exe';
    chromeDriver=r'driver\chromedriver.exe'
    headers={
        'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8',
        'Accept-Encoding': 'gzip, deflate, br',
        'Accept-Language': 'zh-CN,zh;q=0.9',
        'Cache-Control': 'max-age=0',
        'Connection': 'keep-alive',
        'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.162 Safari/537.36',
    }
    count = SELENIUM_THREAD_COUNT
    maxSize =  SELENIUM_THREAD_COUNT+3

    #程序启动时就初始化（创建浏览器对象）
    @classmethod
    def init(cls,initSize=SELENIUM_THREAD_COUNT, maxSize=SELENIUM_THREAD_COUNT+3):
        for i in range(SELENIUM_THREAD_COUNT):
            print(str(i)+' 对象初始化....')
            SafeObjectPool.queue.put_nowait(cls.tomjs_init())
        cls.count = initSize
        cls.maxSize = maxSize
        print('对象池初始化完成.共初始化：'+str(initSize)+' 个对象')

    @staticmethod
    def getDriver():
        try:
            return SafeObjectPool.queue.get_nowait()
        except Empty:
            SafeObjectPool.tryNewDriver()
            try:
                return SafeObjectPool.queue.get_nowait()
            except Empty:
                return None

    #使用完后放回对象池
    @staticmethod
    def release(obj):
        try:
            if obj is None:
                return
            SafeObjectPool.queue.put_nowait(obj)
        except Full:
           return

    @classmethod
    def tryNewDriver(cls):
        cls.locker.acquire()
        if cls.count < cls.maxSize:
            try:
                cls.queue.put_nowait(cls.tomjs_init())
                cls.count =+ 1
            except Full:
                pass
        cls.locker.release()

    @classmethod
    def tomjs_init(cls,retry=False):
        # dcap = dict(DesiredCapabilities.PHANTOMJS)
        dcap = DesiredCapabilities.PHANTOMJS.copy()
        # 从USER_AGENTS列表中随机选一个浏览器头，伪装浏览器
        agent = generate_user_agent(os=('mac', 'linux', 'win'))
        dcap["phantomjs.page.settings.userAgent"] = agent
        for key, value in cls.headers.items():
            dcap['phantomjs.page.customHeaders.{}'.format(key)] = value
        # 不载入图片，爬页面速度会快很多
        dcap["phantomjs.page.settings.loadImages"] = False
        #是否启用js
        dcap["phantomjs.page.settings.javascriptEnabled"] = True
        dcap["phantomjs.page.settings.browserName"] = 'Chrome'
        # 利用DesiredCapabilities(代理设置)参数值，重新打开一个sessionId，我看意思就相当于浏览器清空缓存后，加上代理重新访问一次url
        # proxy = webdriver.Proxy()
        # proxy.proxy_type = ProxyType.MANUAL
        # proxy.http_proxy = random.choice(ips)
        # proxy.add_to_capabilities(dcap)
        # #打开带配置信息的phantomJS浏览器
        # tomjs = PhantomJS(tomJsDriver, desired_capabilities=dcap)
        tomjs = PhantomJS(cls.tomJsDriver)
        # 隐式等待5秒，可以自己调节
        tomjs.implicitly_wait(6)
        # 设置10秒页面超时返回，类似于requests.get()的timeout选项，driver.get()没有timeout选项
        # 以前遇到过driver.get(url)一直不返回，但也不报错的问题，这时程序会卡住，设置超时选项能解决这个问题。
        tomjs.set_page_load_timeout(10)
        # 设置10秒脚本超时时间
        tomjs.set_script_timeout(10)
        return tomjs

    @classmethod
    def chrome_init(cls,retry=False):
        session = Session()
        session.headers.clear()
        option = webdriver.ChromeOptions()
        # option.add_argument('headless')
        option.add_argument('disable-infobars')
        # option.add_argument('--proxy-server='+web)
        for key, value in cls.headers.items():
            if 'Cookie'!=key:
                option.add_argument(
                    key+'="'+value+'"')
        tomjs =Chrome(executable_path=cls.chromeDriver,chrome_options=option)
        return tomjs;